package com.example.demo.common.generator;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;

import com.example.demo.common.generator.template.ReplaceMark;
import com.example.demo.common.generator.template.Templates;
import com.example.demo.common.generator.util.Underline2Camel;

/**
 * Mybatis手动执行类
 * @author Administrator
 * @createTime 2018年12月27日 上午3:51:39
 */
public class MybatisGeneratorExecutor {
    
    public static void main(String[] args) throws Exception {
        try {
            MybatisGeneratorExecutor.generator();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    @SuppressWarnings("resource")
    public static void generator() throws Exception {
        List<String> warnings = new ArrayList<String>();
        boolean overwrite = true;
        File configFile = new File("src/main/resources/generatorConfig.xml");
        ConfigurationParser cp = new ConfigurationParser(warnings);
        Configuration config = cp.parseConfiguration(configFile);
        DefaultShellCallback callback = new DefaultShellCallback(overwrite);
        MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
        myBatisGenerator.generate(null);

        extendJob();
        System.out.println("complete!");
    }

    private static void extendJob() {
        Properties properties = new Properties();
        try (FileInputStream inputStream = new FileInputStream("src/main/resources/generator.properties")) {
            properties.load(inputStream);
            String modulePath = properties.getProperty("generator.modulePath");
            String tableName = properties.getProperty("generator.tableName");
            String className = properties.getProperty("generator.className");
            if (tableName.contains("%")) {
                return;
            }
            if (null != className && !"".equals(className.trim())) {
                tableName = className;
            }
            tableName = Underline2Camel.underline2Camel(tableName, false);
            String tableNameField = Character.toLowerCase(tableName.charAt(0)) + tableName.substring(1);
            String fullMoudulePath = System.getProperty("user.dir") + "\\src\\main\\java\\"
                    + modulePath.replace(".", "\\");

            if ("true".equals(properties.getProperty("generator.service").trim())) {
                createService(modulePath, tableName, tableNameField, fullMoudulePath);

            }

            if ("true".equals(properties.getProperty("generator.controller").trim())) {
                boolean useRest = "true".equals(properties.getProperty("rest.controller").trim());
                createController(modulePath, tableName, fullMoudulePath, useRest);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }



    private static void createService(String modulePath, String tableName, String tableNameField,
            String fullMoudulePath) throws IOException, FileNotFoundException {
        File service = new File(fullMoudulePath + "\\service");
        if (!service.exists()) {
            service.mkdir();
        }
        File serviceClass = new File(fullMoudulePath + "\\service\\" + tableName + "Service.java");
        if (!serviceClass.exists()) {                    
            serviceClass.createNewFile();
        }
        FileOutputStream serviceClassfileOutputStream = new FileOutputStream(serviceClass);

        serviceClassfileOutputStream.write(
                Templates.TEMPLATE_SERVICE.getValue().replace(ReplaceMark.MODULE_PATH.getValue(), modulePath)
                        .replace(ReplaceMark.TABLE_NAME.getValue(), tableName).getBytes());
        serviceClassfileOutputStream.flush();
        serviceClassfileOutputStream.close();

        File impl = new File(fullMoudulePath + "\\service\\impl");
        if (!impl.exists()) {
            impl.mkdir();
        }
        File serviceImplClass = new File(
                fullMoudulePath + "\\service\\impl\\" + tableName + "ServiceImpl.java");
        if (!serviceImplClass.exists()) {
            serviceImplClass.createNewFile();
        }
        FileOutputStream serviceImplClassfileOutputStream = new FileOutputStream(serviceImplClass);

        serviceImplClassfileOutputStream.write(Templates.TEMPLATE_SERVICE_IMPL.getValue()
                .replace(ReplaceMark.MODULE_PATH.getValue(), modulePath)
                .replace(ReplaceMark.TABLE_NAME.getValue(), tableName)
                .replace(ReplaceMark.TABLE_NAME_FIELD.getValue(), tableNameField).getBytes());
        serviceImplClassfileOutputStream.flush();
        serviceImplClassfileOutputStream.close();
    }
    
    private static void createController(String modulePath, String tableName, String fullMoudulePath, boolean useRest)
            throws IOException {
        File controller = new File(fullMoudulePath + "\\controller");
        System.out.println(controller.getPath());
        if (!controller.exists()) {
            controller.mkdir();
        }
        File controllerClass = new File(fullMoudulePath + "\\controller\\" + tableName + "Controller.java");
        if (!controllerClass.exists()) {
            controllerClass.createNewFile();
        }
        FileOutputStream controllerClassfileOutputStream = new FileOutputStream(controllerClass);

        Templates templates = useRest ? Templates.TEMPLATE_REST_CONRTOLLER : Templates.TEMPLATE_CONTROLLER;

        System.out.println(templates.getValue());

        controllerClassfileOutputStream
                .write(templates.getValue().replace(ReplaceMark.MODULE_PATH.getValue(), modulePath)
                        .replace(ReplaceMark.TABLE_NAME.getValue(), tableName).getBytes());
        controllerClassfileOutputStream.flush();
        controllerClassfileOutputStream.close();
    }

}